package gameAppLayer;

import java.io.IOException;
import java.util.ArrayList;

import gameAppLayer.stateMachine.strategyState.GlobalLODControl;

import com.jme3.collision.MotionAllowedListener;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.input.InputManager;
import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.AnalogListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.input.controls.MouseAxisTrigger;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.Control;

public class StrategyCamera extends AbstractRealCamera implements AnalogListener, ActionListener {
	
	protected boolean dragToRotate = false;
    protected boolean canRotate = false;
    protected InputManager inputManager;
    
    public StrategyCamera(Camera cam) {
    	this.setCamera(cam);
    }
    
//    public StrategyCamera(Camera cam, Spatial spatial) {
//    	this.setCamera(cam);    	
//    	
//    	updateSpatialLocation();
//    }
    
    public void registerInputs(InputManager inputManager) {
    	this.inputManager = inputManager;
    	
    	String[] mappings = new String[] {
    		"STRATCAM_STRAFELEFT",
    		"STRATCAM_STRAFERIGHT",
    		"STRATCAM_STRAFEUP",
    		"STRATCAM_STRAFEDOWN",
    		
    		"STRATCAM_ZOOMIN",
    		"STRATCAM_ZOOMOUT"
    	};
    	
    	inputManager.addMapping("STRATCAM_STRAFELEFT", new KeyTrigger(KeyInput.KEY_A));
    	inputManager.addMapping("STRATCAM_STRAFERIGHT", new KeyTrigger(KeyInput.KEY_D));
    	inputManager.addMapping("STRATCAM_STRAFEUP", new KeyTrigger(KeyInput.KEY_W));
    	inputManager.addMapping("STRATCAM_STRAFEDOWN", new KeyTrigger(KeyInput.KEY_S));
    	
    	inputManager.addMapping("STRATCAM_ZOOMIN", new KeyTrigger(KeyInput.KEY_Q));
    	inputManager.addMapping("STRATCAM_ZOOMOUT", new KeyTrigger(KeyInput.KEY_E));
    	
//    	inputManager.addMapping("STRATCAM_ZOOMIN", new MouseAxisTrigger(MouseInput.AXIS_WHEEL, false));
//    	inputManager.addMapping("STRATCAM_ZOOMOUT", new MouseAxisTrigger(MouseInput.AXIS_WHEEL, true));
    	
    	inputManager.addListener(this, mappings);
    	inputManager.setCursorVisible(true);
    	
    }    

    
    protected void zoomCamera(float value) {
    	Vector3f vel = new Vector3f();
    	Vector3f pos = cam.getLocation().clone();
    	System.out.println(value);
    	if ((pos.z > 1.5) || ((pos.z <=1.5)&&(value < 0))){
    		cam.getDirection(vel);
        	
        	vel.multLocal(value*this.zoomSpeed);
        	
        	if (motionAllowed!=null)
        		motionAllowed.checkMotionAllowed(pos, vel);
        	else
        		pos.addLocal(vel);
        	
        	cam.setLocation(pos); 
        	
//        	System.out.println(pos.x + " " + pos.y + " " + pos.z);
        	
        	updateSpatialLocation();
    	}
    	else if ((pos.z <= 1.5)&&(value > 0)) {
    		pos.z = 1.5f;
    		cam.setLocation(pos);    		
//    		System.out.println(pos.x + " " + pos.y + " " + pos.z);
    		updateSpatialLocation();
    	}    	
    }
    
    //Taken from FlyByCamera
    protected void moveCamera(float value, boolean sideways) {
    	
    	Vector3f vel = new Vector3f();
    	Vector3f pos = cam.getLocation().clone();
    	
    	if (sideways) {
    		cam.getLeft(vel);
    	}
    	else {
    		cam.getUp(vel);
    	}
    	vel.multLocal(value*moveSpeed);
    	
    	if (motionAllowed!=null)
    		motionAllowed.checkMotionAllowed(pos, vel);
    	else
    		pos.addLocal(vel);
    	
    	cam.setLocation(pos);    
    	
    	updateSpatialLocation();
    }
    
	public void onAction(String name, boolean isPressed, float tpf) {
		if (!enabled)
			return;		
	}

	public void onAnalog(String name, float value, float tpf) {
		if (!enabled)
			return;
		
		if (name.equals("STRATCAM_STRAFELEFT")) {
			moveCamera(value, true);
		}
		else if (name.equals("STRATCAM_STRAFERIGHT")) {
			moveCamera(-value, true);
		}
		else if (name.equals("STRATCAM_STRAFEUP")) {
			moveCamera(value, false);
		}
		else if (name.equals("STRATCAM_STRAFEDOWN")) {
			moveCamera(-value, false);
		}
		else if (name.equals("STRATCAM_ZOOMIN")) {
			zoomCamera(value);
		}
		else if (name.equals("STRATCAM_ZOOMOUT")) {
			zoomCamera(-value);
		}		
	}

	public Control cloneForSpatial(Spatial spatial) {
		StrategyCamera other = new StrategyCamera(cam);
		other.registerInputs(inputManager);
		other.setSpatial(spatial);
		return other;
	}

	@Override
	protected void controlUpdate(float tpf) {
		
		
	}

	@Override
	protected void controlRender(RenderManager rm, ViewPort vp) {
		if (this.spatial!=null)
			updateSpatialLocation();
		
	}
}



//Taken from FlyByCamera.java
//protected void zoomCamera(float value) {
//	float h = cam.getFrustumTop();
//  float w = cam.getFrustumRight();
//  float aspect = w / h;
//
//  float near = cam.getFrustumNear();
//
//  float fovY = FastMath.atan(h / near)
//            / (FastMath.DEG_TO_RAD * .5f);
//  fovY += value * 0.1f;
//
//  h = FastMath.tan( fovY * FastMath.DEG_TO_RAD * .5f) * near;
//  w = h * aspect;
//
//  cam.setFrustumTop(h);
//  cam.setFrustumBottom(-h);
//  cam.setFrustumLeft(-w);
//  cam.setFrustumRight(w);
//}
